package com.silence.gmall.util;

import cn.hutool.core.util.IdUtil;
import com.silence.gmall.enums.TraceIdType;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Objects;
import java.util.function.Supplier;

/**
 * @Author silence
 * @Email 792245022@qq.com
 * @Date 2025-06-11 14:50
 * @Description 链路标识工具类
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TraceIdUtil {

    /**
     * 生成指定类型的traceId
     *
     * @param type TraceId类型枚举
     * @return traceId
     */
    public static String generate(TraceIdType type) {
        return switch (type) {
            case MQ -> generateTraceId(TraceIdType.MQ::getPrefix);
            case JOB -> generateTraceId(TraceIdType.JOB::getPrefix);
            case OUT -> generateTraceId(TraceIdType.OUT::getPrefix);
            default -> generateTraceId(TraceIdType.IN::getPrefix);
        };
    }

    /**
     * 生成链路标识
     *
     * @param supplier 前缀生成器
     * @return traceId
     */
    public static String generateTraceId(Supplier<String> supplier) {
        if (Objects.isNull(supplier)) {
            return IdUtil.simpleUUID();
        }
        return supplier.get() + "-" + IdUtil.simpleUUID();
    }

    /**
     * 是否来自MQ发起的线程
     *
     * @param traceId traceId
     * @return true=是
     */
    public static Boolean fromMq(String traceId) {
        return StringUtils.isNotBlank(traceId) && traceId.startsWith(TraceIdType.MQ.getPrefix());
    }

    /**
     * 是否来自JOB发起的线程
     *
     * @param traceId traceId
     * @return true=是
     */
    public static Boolean fromJob(String traceId) {
        return StringUtils.isNotBlank(traceId) && traceId.startsWith(TraceIdType.JOB.getPrefix());
    }

    /**
     * 是否来自外部发起的线程
     *
     * @param traceId traceId
     * @return true=是
     */
    public static Boolean fromOut(String traceId) {
        return StringUtils.isNotBlank(traceId) && traceId.startsWith(TraceIdType.OUT.getPrefix());
    }

    /**
     * 是否来自内部发起的线程
     *
     * @param traceId traceId
     * @return true=是
     */
    public static Boolean fromIn(String traceId) {
        return StringUtils.isNotBlank(traceId) && traceId.startsWith(TraceIdType.IN.getPrefix());
    }

}
